﻿using System;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Text;
using Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Meta;

namespace Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Pdf
{
    public class PropertyTable
    {
        private string fullIdKey;

        /// <summary>Metadata provider</summary>
        protected IMetaProvider metaProvider;

        /// <summary>All different fonts used</summary>
        protected PdfFonts BookFonts;

        /// <summary>ITextSharp document worker </summary>
        protected Document doc;

        public PdfPTable Table { get; private set; }

        public string QuestFullId { get; set; }

        /// <summary>
        /// Total width allowed to a table
        /// </summary>
        protected float TotalWidth
        {
            get
            {
                return doc.PageSize.Width -doc.LeftMargin - doc.RightMargin;
            }
        }


        public PropertyTable(IMetaProvider mp, PdfFonts fonts, Document pdfDocument)
        {
            metaProvider = mp;
            fullIdKey = metaProvider != null ? metaProvider.FullIdKey : string.Empty;
            doc = pdfDocument;
            BookFonts = fonts;

            CreateTable();
        }

        /// <summary>
        /// Two columns table, as property key and value
        /// </summary>
        /// <returns>created table object</returns>
        protected void CreateTable()
        {
            Table = new PdfPTable(2);
            float[] widths = new float[] { 23f, 77f };
            Table.SetWidths(widths);
            Table.TotalWidth = TotalWidth;
        }

        public void AddMainTitle(string text)
        {
            Phrase ph = new Phrase(text, BookFonts.FontTitle);
            Anchor target = new Anchor(ph);
            target.Name = text;
            PdfPCell cell = new PdfPCell(target);
            cell.MinimumHeight = 12f;
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);
        }

        public void AddAnchoredTitle(string text, string anchorName)
        {
            Phrase ph = new Phrase(text, BookFonts.FontLevelOne);
            Anchor target = new Anchor(ph);
            target.Name = anchorName;
            PdfPCell cell = new PdfPCell(target);
            cell.MinimumHeight = 12f;
            cell.PaddingBottom = 3;
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);
        }

        public void AddAnchoredTitle(string id, string text, string anchorName)
        {
            Phrase ph = new Phrase(id + ": " + text, BookFonts.FontTableHead);
            Anchor target = new Anchor(ph);
            target.Name = anchorName;
            PdfPCell cell = new PdfPCell(target);
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
            cell.MinimumHeight = 12f;
            cell.PaddingBottom = 3;
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);

            //ph = new Phrase(text, BookFonts.FontTableHead);
            //cell = new PdfPCell(ph);
            //cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_HEAD);
            //cell.Border = Rectangle.NO_BORDER;
            //Table.AddCell(cell);
        }
        public void AddAnchoredTitle2(string id, string text, string anchorName)
        {
            Phrase ph = new Phrase(id + ": " + text, BookFonts.FontLevelOne);
            Anchor target = new Anchor(ph);
            target.Name = anchorName;
            PdfPCell cell = new PdfPCell(target);
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_HEAD);
            cell.MinimumHeight = 12f;
            cell.PaddingBottom = 3;
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);

            //ph = new Phrase(text, BookFonts.FontTableHead);
            //cell = new PdfPCell(ph);
            //cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_HEAD);
            //cell.Border = Rectangle.NO_BORDER;
            //Table.AddCell(cell);
        }

        public void AddTitle(string text)
        {
            Phrase ph = new Phrase(text, BookFonts.FontLevelOne);
            PdfPCell cell = new PdfPCell(ph);
            cell.MinimumHeight = 12f;
            cell.PaddingBottom = 3;
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);
        }

        public void AddAnchoredSubTitle(string text, string anchorName)
        {
            Phrase ph = new Phrase(text, BookFonts.FontLevelTwo);
            Anchor target = new Anchor(ph);
            target.Name = anchorName;
            PdfPCell cell = new PdfPCell(target);
            cell.MinimumHeight = 12f;
            cell.Border = Rectangle.NO_BORDER;
            cell.Colspan = 2;
            Table.AddCell(cell);
        }

        public void AddLeading(float padding)
        {

            Phrase ph = new Phrase("", BookFonts.FontLevelTwo);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.NO_BORDER;
            cell.PaddingTop = padding;
            cell.Colspan = 2;
            Table.AddCell(cell);
        }


        public void AddSubTitle(string text)
        {
            AddSubTitle(text, null);
        }

        public void AddSubTitle(string subTitleProperty, string subTitleContent)
        {

            Phrase ph = new Phrase(subTitleProperty, BookFonts.FontLevelTwo);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.NO_BORDER;
            cell.SetLeading(0.0f, 1.4f);

            cell.PaddingTop = 8f;
            if (string.IsNullOrEmpty(subTitleContent))
                cell.Colspan = 2;
            Table.AddCell(cell);

            if (string.IsNullOrEmpty(subTitleContent) == false)
            {
                cell = new PdfPCell(new Phrase(subTitleContent, BookFonts.FontLevelTwo));
                cell.Border = Rectangle.NO_BORDER;
                cell.SetLeading(0.0f, 1.4f);

                cell.PaddingTop = 8f;
                Table.AddCell(cell);
            }
        }

        public void AddProperty(string propertyId, string propertyContent)
        {
            AddProperty(propertyId, propertyContent, false);
        }

        public void AddItalicProperty(string propertyId, string propertyContent)
        {
            AddProperty(propertyId, propertyContent, true);
        }

        protected void AddProperty(string propertyId, string propertyContent, bool isItalic)
        {
            if (string.IsNullOrEmpty(propertyContent))
                return;

            Phrase ph = new Phrase(propertyId, isItalic ?
                    BookFonts.FontPropertyItalic : BookFonts.FontProperty);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.NO_BORDER;
            cell.SetLeading(0.0f, 1.4f);
            cell.PaddingTop = 4f;
            Table.AddCell(cell);

            cell = new PdfPCell(new Phrase(propertyContent, BookFonts.FontStandard));
            cell.Border = Rectangle.NO_BORDER;
            cell.SetLeading(0.0f, 1.4f);
            cell.PaddingTop = 4f;
            cell.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
            Table.AddCell(cell);
        }


        public void AddAnchorProperty(string propertyId, string propertyContent, string anchorReference, bool isItalic)
        {
            if (string.IsNullOrEmpty(propertyContent))
                return;

            Phrase ph = new Phrase(propertyId, isItalic ?
                    BookFonts.FontPropertyItalic : BookFonts.FontProperty);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.NO_BORDER;
            cell.SetLeading(0.0f, 1.4f);
            cell.PaddingTop = 4f;
            Table.AddCell(cell);


            ph = new Phrase(propertyContent, BookFonts.FontStandard);
            cell = new PdfPCell(ph);
            if (string.IsNullOrEmpty(anchorReference) == false)
            {
                Anchor click = new Anchor(ph);
                click.Reference = anchorReference;
                cell = new PdfPCell(click);
            }
            
            cell.Border = Rectangle.NO_BORDER;
            cell.SetLeading(0.0f, 1.4f);
            cell.PaddingTop = 4f;
            cell.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
            Table.AddCell(cell);
        }

        public bool AddAnnotations(List<HierarchyNode> annotList)
        {
            foreach (HierarchyNode annotNode in annotList)
            {
                // Specific annotation related to Questionaire question
                if (string.IsNullOrEmpty(QuestFullId) == false && annotNode.Id == "QUEST_PRINT")
                {
                    string anchorLink = "#" + QuestFullId + "Q" + ExtractQuestId(annotNode.Descr);
                    string typeTitle = "Question Id";
                    AddAnchorProperty(typeTitle, annotNode.Descr, anchorLink, false);
                }
                else
                {
                    string text = annotNode.Descr;
                    if (text.Length > 0 && annotNode.Name.Length > 0)
                        text += " : ";
                    text += annotNode.Name;
                    AddProperty(annotNode.Id, text);
                }
            }
            return annotList.Count > 0;
        }

        protected string ExtractQuestId(string questRange)
        {
            if (questRange == "23.21/22_23.24/28")
            {
                GetQidList(questRange);
            }
            List<string> listId = GetQidList(questRange);
            string qid = listId.Count > 0 ? listId[0] : string.Empty;
            if (qid.Length > 2)
            {
                qid = qid.Substring(0, qid.Length - 2) + "." + qid.Substring(qid.Length - 2);
            }
            return qid;
            //if (questRange.Length > 0)
            //{
            //    string iid = questRange.Split('_')[0];
            //    qid = iid.Split('/')[0];
            //    while (qid.Length < 5)
            //        qid = "0" + qid;
            //}
        }

        public List<string> GetQidList(string questIdDisplay)
        {
            List<string> listId = new List<string>();

            if (questIdDisplay != null && questIdDisplay.Length > 0)
            {
                // Get groups of questions
                string[] arrGrp = questIdDisplay.Split('_');

                foreach (string sRangeId in arrGrp)
                {
                    string[] arrSeparatorId = sRangeId.Split('/');
                    foreach (string sep in arrSeparatorId)
                    {
                        string[] arrIntervalId = sep.Split('-');
                        bool inInterval = false;
                        foreach (string inter in arrIntervalId)
                        {
                            GetId(listId, inter, inInterval);
                            inInterval = true;
                        }

                    }
                }
            }
            return listId;
        }

        private void GetId(List<string> listId, string tag, bool interval)
        {

            // two char, if interval create all val
            if (tag.Length == 2)
            {
                if (interval)
                {
                    int start = Convert.ToInt32(listId[listId.Count - 1].Substring(3, 2));
                    int end = Convert.ToInt32(tag);
                    string baseId = listId[listId.Count - 1].Substring(0, 3);
                    for (int i = start + 1; i <= end; i++)
                    {
                        listId.Add(baseId + i.ToString().PadLeft(2, '0'));
                    }

                }
                else if (listId.Count > 0)
                    listId.Add(listId[listId.Count - 1].Substring(0, 3) + tag);
            }
            else
            {
                string[] arr = tag.Split('.');
                if (arr.Length == 1)
                {
                    listId.Add(arr[0].PadRight(5, '0'));
                }
                else
                {
                    string s = arr[1].Length != 2 ? arr[1].Substring(0, 1) + "0" : arr[1];
                    s = arr[0] + s;
                    listId.Add(s.PadLeft(5, '0'));
                }

            }

            // 3, 4,5 chars without period, create new id

        }

    }
}
